﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using System.Threading;
using System.ServiceModel;

namespace Harkon.AppServer.cOne.Service.Remote
{
    [ServiceBehavior(
        IncludeExceptionDetailInFaults = true,
        InstanceContextMode = InstanceContextMode.Single,
        ConcurrencyMode = ConcurrencyMode.Multiple
        )]
    public class RemoteCallService : AbstractService, IRemoteCall
    {

        private static ILog logger = LogManager.GetLogger(typeof(RemoteCallService));
        private Thread serviceHostThread;
        private ServiceHost serviceHost;

        public string ServiceUri { get; private set; }

        #region Execution of target method

        public object Execute(string[] parameters)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region ILifecycleAware Members

        public override bool Init()
        {
            if (base.Init())
            {
                //create service host with this instance as hosted class
                serviceHost = new ServiceHost(this);

                serviceHostThread = new Thread(Run);
                serviceHostThread.Name = "RemoteCall";
                serviceHostThread.IsBackground = true;
                ServiceUri = serviceHost.BaseAddresses[0].AbsoluteUri;
                logger.InfoFormat("The remote call service host url={0}", serviceHost.BaseAddresses[0].AbsoluteUri);
                logger.Debug("Remote call service initialized");
                return true;
            }
            return false;
        }

        public override bool Start()
        {
            if (base.Start())
            {
                serviceHostThread.Start();
                logger.Debug("Remote call service running");
                return true;
            }
            return false;
        }

        public override bool Stop()
        {
            if (base.Stop())
            {
                lock (this)
                {
                    Monitor.Pulse(this);
                }
                logger.Debug("Remote call service stopped");
                return true;
            }
            return false;
        }

        #endregion

        #region ServiceHost related

        private void Run()
        {
            //start service host
            try
            {
                serviceHost.Open();
                logger.Info("The remote call service host is up and running.");
                lock (this)
                {
                    Monitor.Wait(this);
                }

                logger.Warn("The remote call service host is closing...");
                serviceHost.Close();
                logger.Warn("The remote call service host is closed!");
            }
            catch (CommunicationException ce)
            {
                logger.Fatal(ce.Message, ce);
                serviceHost.Abort();
            }
        }

        #endregion
    }
}
